package cool.xiaokang.familyaccount.controller;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.servlet.ServletOutputStream;

import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.CellRangeAddress;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.struts2.ServletActionContext;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;

import com.alibaba.fastjson.serializer.PropertyFilter;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;

import cool.xiaokang.familyaccount.pojo.OutAccount;
import cool.xiaokang.familyaccount.pojo.OutAccountType;
import cool.xiaokang.familyaccount.pojo.User;
import cool.xiaokang.familyaccount.service.OutAccountService;
import cool.xiaokang.familyaccount.service.OutAccountTypeService;
import cool.xiaokang.familyaccount.service.UserService;
import cool.xiaokang.familyaccount.utils.DateFormateUtil;
import cool.xiaokang.familyaccount.utils.FileUtils;
import cool.xiaokang.familyaccount.utils.ResponseUtils;
import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
@Controller
@Scope("prototype")
public class OutAccountAction extends ActionSupport implements ModelDriven<OutAccount> {
	private static final long serialVersionUID = -8298371293348684700L;

	@Autowired
	private OutAccountService outAccountService;

	@Autowired
	private OutAccountTypeService outAccountTypeService;

	@Autowired
	private UserService userService;

	private Date startTime;
	private Date endTime;
	private String desc;
	private String year;
	private OutAccount outAccount = new OutAccount();
	private File myFile;

	public String getStartTime() {
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		return format.format(startTime);
	}

	public String getEndTime() {
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		return format.format(endTime);
	}

	// 为首页准备6条支出账单（支出金额降序）
	public String findSixOutAccount() throws Exception {
		User user = (User) ActionContext.getContext().getSession().get("currentUser");
		List<OutAccount> findSixOutAccount = outAccountService.findSixOutAccount(user.getUser_id());
		PropertyFilter filter = new PropertyFilter() {
			@Override
			public boolean apply(Object object, String name, Object value) {
				boolean flag = true;
				if (name.equals("user")) {
					flag = false;
				}
				return flag;
			}
		};
		ResponseUtils.respListRef(ServletActionContext.getResponse(), findSixOutAccount, filter);
		return NONE;
	}

	// 进入支出账单jsp
	public String list() throws Exception {
		return "toList";
	}

	// 当前用户的支出账单（收入时间降序）
	public String listCurrentUser() throws Exception {
		DetachedCriteria dc = DetachedCriteria.forClass(OutAccount.class);
		User user = (User) ActionContext.getContext().getSession().get("currentUser");
		dc.add(Restrictions.eq("user.user_id", user.getUser_id()));
		dc.addOrder(Order.desc("outaccount_datetime"));
		if (startTime != null || endTime != null) {
			if (startTime != null && endTime != null) {
				dc.add(Restrictions.between("outaccount_datetime", startTime, endTime));
			} else {
				dc.add(Restrictions.like("outaccount_datetime", startTime != null ? startTime : endTime));
			}
		}
		if (StringUtils.isNotBlank(desc)) {
			outAccount.setOutaccount_desc(desc);
			dc.add(Restrictions.like("outaccount_desc", "%" + outAccount.getOutaccount_desc() + "%"));
		}
		List<OutAccount> outAccounts = outAccountService.findList(dc);
		PropertyFilter filter = new PropertyFilter() {
			@Override
			public boolean apply(Object object, String name, Object value) {
				boolean flag = true;
				if (name.equals("user")) {
					flag = false;
				}
				return flag;
			}
		};
		ResponseUtils.respListRef(ServletActionContext.getResponse(), outAccounts, filter);
		return NONE;
	}

	/**
	 * 上传支出账单
	 * 
	 * @throws IOException
	 * @throws ParseException
	 * @throws Exception
	 */
	public String upload() throws IOException {
		HSSFWorkbook workbook;
		String flag = "1";
		try {
			workbook = new HSSFWorkbook(new FileInputStream(myFile));
			HSSFSheet sheet = workbook.getSheetAt(0);
			List<OutAccount> list = new ArrayList<OutAccount>();
			User user = (User) ActionContext.getContext().getSession().get("currentUser");
			for (Row row : sheet) {
				if (row.getRowNum() == 0 || row.getRowNum() == 1) {
					continue;
				}
				String typename = row.getCell(0).getStringCellValue();
				String outaccount_money = "";
				if (row.getCell(1) != null) {
					row.getCell(1).setCellType(Cell.CELL_TYPE_STRING);
					outaccount_money = row.getCell(1).getStringCellValue();
				}
				String outaccount_datatimeStr = "";
				if (row.getCell(2) != null) {
					row.getCell(2).setCellType(Cell.CELL_TYPE_STRING);
					outaccount_datatimeStr = row.getCell(2).getStringCellValue();
				}
				String outaccount_desc = row.getCell(3).getStringCellValue();
				SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
				Date outaccount_datatime = sdf.parse(outaccount_datatimeStr);
				OutAccount outAccount1 = new OutAccount(outaccount_datatime, Double.valueOf(outaccount_money),
						outaccount_desc, new Date());
				OutAccountType outAccountType1 = new OutAccountType();
				outAccountType1.setOutaccounttype_name(typename);
				outAccount1.setOutAccountType(outAccountType1);
				outAccount1.setUser(user);
				list.add(outAccount1);
			}
			outAccountService.saveOutAccount(list, user.getUser_id());
		} catch (Exception e) {
			flag = "0";
			e.printStackTrace();
		}
		ServletActionContext.getResponse().getWriter().write(flag);
		return NONE;
	}

	/**
	 * 下载支出账单
	 */
	public String download() throws IOException {
		DetachedCriteria dc = DetachedCriteria.forClass(OutAccount.class);
		User user = (User) ServletActionContext.getContext().getSession().get("currentUser");
		dc.add(Restrictions.eq("user.user_id", user.getUser_id()));
		dc.addOrder(Order.asc("outaccount_datetime"));
		List<OutAccount> list = outAccountService.findList(dc);
		HSSFWorkbook workbook = new HSSFWorkbook();
		HSSFSheet sheet = workbook.createSheet("支出账单");
		sheet.setDefaultColumnWidth(20);// 默认宽度

		// 第一行蓝色宋体加粗
		HSSFCellStyle cellStyle1 = workbook.createCellStyle();
		cellStyle1.setAlignment(HSSFCellStyle.ALIGN_CENTER);// 居中
		HSSFFont fontStyle1 = workbook.createFont();
		fontStyle1.setFontName("宋体"); // 字体样式
		fontStyle1.setColor(HSSFColor.BLUE.index);
		fontStyle1.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);// 加粗
		fontStyle1.setFontHeightInPoints((short) 14);// 字体大小
		cellStyle1.setFont(fontStyle1);

		HSSFCellStyle cellStyle = workbook.createCellStyle();
		cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);// 居中
		HSSFFont createFont = workbook.createFont();
		createFont.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);// 加粗
		createFont.setFontHeightInPoints((short) 11);// 字体大小
		cellStyle.setFont(createFont);

		// 创建一行
		HSSFRow row = sheet.createRow(0);
		HSSFCell createCell = row.createCell(0);
		createCell.setCellValue("用户【" + user.getUser_name() + "】-支出账单");
		createCell.setCellStyle(cellStyle1);
		sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, 3));

		// 设置头信息
		HSSFRow row2 = sheet.createRow(1);
		HSSFCell cell = row2.createCell(0);
		cell.setCellValue("支出类型");
		cell.setCellStyle(cellStyle);
		HSSFCell cell2 = row2.createCell(1);
		cell2.setCellValue("支出金额");
		cell2.setCellStyle(cellStyle);
		HSSFCell cell3 = row2.createCell(2);
		cell3.setCellValue("支出日期");
		cell3.setCellStyle(cellStyle);
		HSSFCell cell4 = row2.createCell(3);
		cell4.setCellValue("备注");
		cell4.setCellStyle(cellStyle);
		for (OutAccount outAccount1 : list) {
			HSSFRow dataRow = sheet.createRow(sheet.getLastRowNum() + 1);
			dataRow.createCell(0).setCellValue(outAccount1.getOutAccountType().getOutaccounttype_name());
			dataRow.createCell(1).setCellValue(outAccount1.getOutaccount_money());
			dataRow.createCell(2).setCellValue(DateFormateUtil.transferHaveTime(outAccount1.getOutaccount_datetime()));
			dataRow.createCell(3).setCellValue(outAccount1.getOutaccount_desc());
		}
		// 下载
		String filename = "用户" + user.getUser_name() + "_支出账单_" + System.currentTimeMillis() + ".xls";
		String contentType = ServletActionContext.getServletContext().getMimeType(filename);
		ServletOutputStream stream = ServletActionContext.getResponse().getOutputStream();
		ServletActionContext.getResponse().setContentType(contentType);
		String agent = ServletActionContext.getRequest().getHeader("User-Agent");
		filename = FileUtils.encodeDownloadFilename(filename, agent);
		ServletActionContext.getResponse().setHeader("content-disposition", "attachment;filename=" + filename);
		workbook.write(stream);
		return NONE;
	}

	/**
	 * 根据ID删除支出账单
	 * 
	 * @return
	 */
	public String delete() {
		outAccountService.deleteById(outAccount.getOutaccount_id());
		return "toShow";
	}

	/**
	 * 添加支出账单
	 * 
	 * @return
	 * @throws Exception
	 */
	public String add() throws Exception {
		User user = (User) ActionContext.getContext().getSession().get("currentUser");
		outAccount.setUser(user);
		outAccountService.save(outAccount);
		return "toShow";
	}

	// 用来回显修改
	public String findById() throws Exception {
		OutAccount outAccount1 = outAccountService.findById(outAccount.getOutaccount_id());
		PropertyFilter filter = new PropertyFilter() {
			@Override
			public boolean apply(Object object, String name, Object value) {
				boolean flag = true;
				if (name.equals("outaccounts")) {
					flag = false;
				} else if (name.equals("user")) {
					flag = false;
				}
				return flag;
			}
		};
		ResponseUtils.respObjAndFilter(ServletActionContext.getResponse(), outAccount1, filter);
		return NONE;
	}

	// 修改收入账单
	public String update() {
		User user = (User) ActionContext.getContext().getSession().get("currentUser");
		outAccount.setUser(user);
		outAccountService.update(outAccount);
		return "toShow";
	}

	// 根据类型分类查询当前年或某年支出账单金额总和
	public String findOutAccountGroupByOutAccountTypeName() throws Exception {
		User user = (User) ActionContext.getContext().getSession().get("currentUser");
		List<Object> list = outAccountService.findOutAccountGroupByOutAccountTypeName(user.getUser_id(), year);
		ResponseUtils.respObj(ServletActionContext.getResponse(), list);
		return NONE;
	}

	// 根据账单类型分类查询出当年或某年中各个月的支出账单总和
	public String findOutAccountWithYearly() throws Exception {
		User user = (User) ActionContext.getContext().getSession().get("currentUser");
		List<Object> yearly = new ArrayList<Object>(0);
		List<Object> perYearList = outAccountService.findOutAccountGroupByOutAccountTypeName(user.getUser_id(), year);
		List<Object> perMonthList = outAccountService.findOutAccountWithYearly(user.getUser_id(), year);
		List<Object> perMonthAvgMoney = outAccountService.findPerMonthAvgMoney(user.getUser_id(), year);
		yearly.add(perYearList);
		yearly.add(perMonthList);
		yearly.add(perMonthAvgMoney);
		// System.out.println(JSON.toJSONString(yearly));
		ResponseUtils.respObj(ServletActionContext.getResponse(), yearly);
		return NONE;
	}

	@Override
	public OutAccount getModel() {
		return outAccount;
	}

}
